<!--
 * @Author: 小花
 * @Date: 2022-04-07 14:29:14
 * @LastEditors: 小花
 * @LastEditTime: 2022-06-14 11:44:46
 * @FilePath: /adminClient/src/views/Login/LoginView.vue
 * @Description:登录
-->
<template>
  <div class="LoginPage">
    <!-- Backgrounds -->
    <div id="login-bg" class="container-fluid">
      <div class="bg-img"></div>
      <div class="bg-color"></div>
    </div>
    <!-- End Backgrounds -->
    <div class="container" id="login">
      <div class="row justify-content-center">
        <div class="col-lg-8">
          <div class="login">
            <h1>Login</h1>
            <!-- Loging form -->
            <form>
              <div class="form-group">
                <input type="text" v-model="loginInfo.account" class="form-control" id="exampleInputEmail1"
                  aria-describedby="emailHelp" placeholder="Account">
              </div>
              <div class="form-group">
                <input type="password" v-model="loginInfo.password" class="form-control" id="exampleInputPassword1"
                  placeholder="Password">
              </div>
              <br>
              <button type="button" @click="submit" class="btn btn-lg btn-block btn-success">
                Sign in
              </button>
            </form>
            <!-- End Loging form -->
          </div>
        </div>
      </div>
    </div>
  </div>

</template>

<script lang="ts">
import { defineComponent, reactive, toRefs } from 'vue'

import { useStore } from '@/plugins/store/store'
import { responseEnum, responseUtil } from '@/plugins/request/responseUtil'
import { pubKeyEncrypt, verify } from '@/plugins/encrypt/rsa'
import router from '@/plugins/router/router'
import { PullKey, LoginStart, verifyLoginOverdue } from '@/plugins/request/http'

import { ElMessage } from 'element-plus'
import { ISignData } from '@/model/Login/support/SignInfo'
import LoginViewData from '@/model/Login/LoginView'
import nProgress from 'nprogress'
import _cloneDeep from 'lodash/cloneDeep'

export default defineComponent({
  name: 'LoginView',
  setup () {
    const store = useStore()
    const coreData = reactive(new LoginViewData())

    const submit = async () => {
      nProgress.start()
      const verifyResult = await checkLoginState()
      if (verifyResult) {
        router.replace({ path: '/MainView' })
        nProgress.done()
        return
      }
      if (!store.publicKey) store.publicKey = await getKey()
      const copyData = _cloneDeep(coreData.loginInfo)
      await import('ts-md5/dist/md5').then(module => {
        copyData.account = module.Md5.hashStr(coreData.loginInfo.account)
        copyData.password = module.Md5.hashStr(coreData.loginInfo.password)
      })

      const enCopyData = pubKeyEncrypt(store.publicKey, JSON.stringify(copyData))
      if (!enCopyData) { nProgress.done(); throw new Error('Data encrypt appear error') }
      LoginStart(enCopyData).then(res => {
        if (res.data.code !== responseEnum.LOGIN_SUCCESS) {
          ElMessage.error(res.data.msg)
          nProgress.done()
          return
        }
        store.userData = res.data.data
        ElMessage.success(res.data.msg)
        router.replace({ path: '/MainView' })
        nProgress.done()
      }).catch(() => { nProgress.done() })
    }

    /**
     * @description: 重复登录检测
     * @param {*} Promise
     * @return {*}
     */
    const checkLoginState = async (): Promise<boolean> => {
      if (store.userData && Object.keys(store.userData).length) {
        const result: responseUtil = await (await verifyLoginOverdue()).data
        if (result.code === responseEnum.LOGIN_VALID) {
          return true
        }
      }
      return false
    }

    /**
     * @description: 获取密钥
     * @param {*} Promise
     * @return {*}
     */
    const getKey = (): Promise<string> => {
      return new Promise((resolve, reject) => {
        PullKey().then((res: responseUtil) => {
          if (res.data.code !== responseEnum.OK) {
            ElMessage.error(res.data.msg)
            reject(res.data.msg)
          }
          const map: ISignData = res.data.data
          if (!verify(map.publicKey, map.strAbs, map.strAbsSign)) reject(new Error('数字签名认证失败，请刷新页面重试'))
          store.publicKey = map.publicKey
          console.log('签名认证成功')
          resolve(map.publicKey)
        })
      })
    }
    getKey()

    return {
      ...toRefs(coreData),
      submit
    }
  }
})
</script>

<style lang='scss' scoped>
@import url(https://fonts.googleapis.com/css?family=Montserrat);
@import url('@/assets/css/bootstrap.min.css');

.LoginPage {
  font-family: 'Montserrat', sans-serif;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

#login-bg.container-fluid {
  padding: 0;
  height: 100%;
  position: absolute;
}

/* Background image an color divs*/

.bg-img,
.bg-color {
  min-width: 50%;
  vertical-align: top;
  padding: 0;
  margin-left: 0;
  height: 100%;
  background-color: #caf0d3;
  display: inline-block;
  overflow: hidden;
}

.bg-color {
  margin-left: -5px;
}

.bg-img {
  background-image: url('@/assets/bg-image.jpeg');
  background-size: cover;
}

#login {
  padding-top: 10%;
  text-align: center;
  text-transform: uppercase;
}

.login {
  width: 100%;
  height: 500px;
  background-color: #fff;
  padding: 15px;
  padding-top: 30px;
}

.login h1 {
  margin-top: 30px;
  font-weight: bold;
  font-size: 60px;
  letter-spacing: 3px;
}

.login form {
  max-width: 420px;
  margin: 30px auto;
}

.login .btn {
  border-radius: 50px;
  text-transform: uppercase;
  font-weight: bold;
  letter-spacing: 2px;
  font-size: 20px;
  padding: 14px;
  background-color: #00b72e;
}

.form-group input {
  font-size: 20px;
  font-weight: lighter;
  border: none;
  background-color: #f0f0f0;
  color: #465347 !important;
  padding: 26px 30px;
  border-radius: 50px;
  transition: 0.2s;
}

/* Form check styles*/

.form-check {
  padding: 0;
  text-align: left;
}

.form-check label {
  vertical-align: top;
  padding-top: 5px;
  padding-left: 5px;
  font-size: 15px;
  color: #606060;
  font-size: 14px;
}

.forgot-password {
  text-align: right;
  float: right;
  font-weight: bold;
}

.forgot-password a {
  color: #00b72e;
  opacity: 0.6;
}

.forgot-password a:hover {
  opacity: 1;
}

/* Switch styles */

.switch {
  position: relative;
  display: inline-block;
  width: 60px;
  height: 30px;
}

/* Hide default HTML checkbox */
.switch input {
  display: none;
}

/* The slider */
.slider {
  position: absolute;
  cursor: pointer;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: #f0f0f0;
  -webkit-transition: 0.4s;
  transition: 0.4s;
  border-radius: 30px;
}

.slider:before {
  position: absolute;
  content: '';
  height: 22px;
  width: 22px;
  left: 4px;
  bottom: 4px;
  background-color: white;
  -webkit-transition: 0.4s;
  transition: 0.4s;
  border-radius: 50%;
}

input:checked+.slider {
  background-color: #00b72e;
}

input:focus+.slider {
  box-shadow: 0 0 1px #00b72e;
}

input:checked+.slider:before {
  -webkit-transform: translateX(30px);
  -ms-transform: translateX(30px);
  transform: translateX(30px);
}

/* Media queries */

@media (max-width: 500px) {

  .bg-img,
  .bg-color {
    min-width: 100%;
    height: 50%;
    margin: 0;
  }

  .forgot-password {
    text-align: right;
    float: left;
    padding: 20px 0;
  }

  #login {
    padding-top: 50px;
  }
}
</style>
